/*
 * DocumentationPanel.java
 *
 * Created on 11.02.2009, 16:46:11
 */
package de.blitzcoder.collide.gui.docs;

import de.blitzcoder.collide.docs.Documentation;
import de.blitzcoder.collide.docs.Module;
import de.blitzcoder.collide.docs.Scope;
import de.blitzcoder.collide.engine.parser.CodeConstant;
import de.blitzcoder.collide.engine.parser.CodeField;
import de.blitzcoder.collide.engine.parser.CodeFunction;
import de.blitzcoder.collide.engine.parser.CodeGlobal;
import de.blitzcoder.collide.engine.parser.CodeMethod;
import de.blitzcoder.collide.engine.parser.CodeObject;
import de.blitzcoder.collide.engine.parser.CodeType;
import de.blitzcoder.collide.gui.IconTreeNode;
import de.blitzcoder.collide.gui.IconTreeRenderer;
import de.blitzcoder.collide.icons.Icon;
import java.util.ListIterator;
import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 *
 * @author blitzcoder
 */
public class DocumentationPanel extends javax.swing.JPanel {

    private Module lastModule = null;

    private static final ImageIcon ICON_SCOPE = Icon.load("folder.png");
    private static final ImageIcon ICON_MODULE = Icon.load("file_bmax.png");
    private static final ImageIcon ICON_CATS = ICON_SCOPE;
    private static final ImageIcon ICON_CONSTANT = Icon.load("tree_constant.png");
    private static final ImageIcon ICON_GLOBAL = Icon.load("menu/website.png");
    private static final ImageIcon ICON_FUNCTION = Icon.load("tree_function.png");
    private static final ImageIcon ICON_TYPE = Icon.load("tree_type.png");
    private static final ImageIcon ICON_FIELD = Icon.load("tree_field.png");
    private static final ImageIcon ICON_METHOD = Icon.load("tree_method.png");


    /** Creates new form DocumentationPanel */
    public DocumentationPanel() {
        initComponents();
        fillModuleTree();
    }

    private void fillModuleTree() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Module");
        DefaultTreeModel model = new DefaultTreeModel(root);

        // Iterate through scopes
        ListIterator<Scope> scopeIt = Documentation.scopeList.listIterator();
        while (scopeIt.hasNext()) {

            // Iterate through modules
            Scope scope = scopeIt.next();
            IconTreeNode scopeNode = new IconTreeNode(scope,ICON_SCOPE);
            root.add(scopeNode);
            ListIterator<Module> modIt = scope.iterateModules();
            while (modIt.hasNext()) {
                Module mod = modIt.next();
                IconTreeNode modNode = new IconTreeNode(mod, ICON_MODULE);
                scopeNode.add(modNode);
            }

        }
        moduleTree.setModel(model);
    }

    private void fillContentTree(Module m) {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(m);
        DefaultTreeModel model = new DefaultTreeModel(root);

        // Create categories
        IconTreeNode constantNode = new IconTreeNode("Konstanten",ICON_CATS);
        IconTreeNode functionNode = new IconTreeNode("Funktionen",ICON_CATS);
        IconTreeNode globalNode = new IconTreeNode("Globals",ICON_CATS);
        IconTreeNode typeNode = new IconTreeNode("Types",ICON_CATS);

        // Add categories
        root.add(constantNode);
        root.add(functionNode);
        root.add(globalNode);
        root.add(typeNode);

        // Iterate through content
        ListIterator<CodeObject> contentIt = m.iterateContent();
        while (contentIt.hasNext()) {

            // Add the Objects
            CodeObject obj = contentIt.next();
            if (documentedCheckbox.isSelected() && obj.getBBDoc().length() == 0)
                if (!(obj instanceof CodeType))
                    continue;


            if (obj instanceof CodeConstant) {
                constantNode.add(new IconTreeNode(obj,ICON_CONSTANT));
            } else if (obj instanceof CodeFunction) {
                functionNode.add(new IconTreeNode(obj,ICON_FUNCTION));
            } else if (obj instanceof CodeGlobal) {
                globalNode.add(new IconTreeNode(obj,ICON_GLOBAL));
            } else if (obj instanceof CodeType) {

                // Add a type and its inner
                IconTreeNode node = new IconTreeNode(obj,ICON_TYPE);
                typeNode.add(node);

                // Create categories
                IconTreeNode typeConstantNode = new IconTreeNode("Konstanten",ICON_CATS);
                IconTreeNode typeFunctionNode = new IconTreeNode("Funktionen",ICON_CATS);
                IconTreeNode typeGlobalNode = new IconTreeNode("Globals",ICON_CATS);
                IconTreeNode typeFieldNode = new IconTreeNode("Felder",ICON_CATS);
                IconTreeNode typeMethodNode = new IconTreeNode("Methoden",ICON_CATS);

                // Add categories
                node.add(typeConstantNode);
                node.add(typeFunctionNode);
                node.add(typeGlobalNode);
                node.add(typeFieldNode);
                node.add(typeMethodNode);

                CodeType type = (CodeType) obj;
                ListIterator<CodeObject> typeIt = type.getChildren().listIterator();
                while (typeIt.hasNext()) {

                    obj = typeIt.next();

                    if (documentedCheckbox.isSelected() && obj.getBBDoc().length() == 0) {
                        continue;
                    }

                    if (obj instanceof CodeConstant) {
                        typeConstantNode.add(new IconTreeNode(obj,ICON_CONSTANT));
                    } else if (obj instanceof CodeFunction) {
                        typeFunctionNode.add(new IconTreeNode(obj,ICON_FUNCTION));
                    } else if (obj instanceof CodeGlobal) {
                        typeGlobalNode.add(new IconTreeNode(obj,ICON_GLOBAL));
                    } else if (obj instanceof CodeField) {
                        typeFieldNode.add(new IconTreeNode(obj,ICON_FIELD));
                    } else if (obj instanceof CodeMethod) {
                        typeMethodNode.add(new IconTreeNode(obj,ICON_METHOD));
                    }


                }


            }

        }

        contentTree.setModel(model);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        splitPane = new javax.swing.JSplitPane();
        jSplitPane1 = new javax.swing.JSplitPane();
        contentTreePanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        contentTree = new javax.swing.JTree();
        documentedCheckbox = new javax.swing.JCheckBox();
        jPanel1 = new javax.swing.JPanel();
        infoPanel = new de.blitzcoder.collide.gui.docs.InfoPanel();
        hideButton = new javax.swing.JButton();
        modulePanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        moduleTree = new javax.swing.JTree();

        setLayout(new java.awt.GridLayout(1, 0));

        contentTreePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Inhalt"));
        contentTreePanel.setLayout(new java.awt.GridBagLayout());

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("Modul");
        contentTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        contentTree.setCellRenderer(new IconTreeRenderer());
        contentTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                contentTreeValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(contentTree);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        contentTreePanel.add(jScrollPane2, gridBagConstraints);

        documentedCheckbox.setText("Nur Dokumentiertes");
        documentedCheckbox.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                documentedCheckboxStateChanged(evt);
            }
        });
        documentedCheckbox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                documentedCheckboxActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        contentTreePanel.add(documentedCheckbox, gridBagConstraints);

        jSplitPane1.setLeftComponent(contentTreePanel);

        jPanel1.setLayout(new java.awt.GridBagLayout());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel1.add(infoPanel, gridBagConstraints);

        hideButton.setText("<");
        hideButton.setToolTipText("Tree verstecken/anzeigen");
        hideButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel1.add(hideButton, gridBagConstraints);

        jSplitPane1.setRightComponent(jPanel1);

        splitPane.setRightComponent(jSplitPane1);

        modulePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Module"));
        modulePanel.setLayout(new java.awt.GridLayout(1, 0));

        moduleTree.setCellRenderer(new IconTreeRenderer());
        moduleTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                moduleTreeValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(moduleTree);

        modulePanel.add(jScrollPane1);

        splitPane.setLeftComponent(modulePanel);

        add(splitPane);
    }// </editor-fold>//GEN-END:initComponents

    private void moduleTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_moduleTreeValueChanged
        Object obj = evt.getPath().getLastPathComponent();
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
        if (node.getUserObject() instanceof Module) {
            lastModule = (Module) node.getUserObject();
            fillContentTree((Module) node.getUserObject());
        }
    }//GEN-LAST:event_moduleTreeValueChanged

    private void documentedCheckboxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_documentedCheckboxStateChanged
    }//GEN-LAST:event_documentedCheckboxStateChanged

    private void documentedCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentedCheckboxActionPerformed
        if (lastModule != null) {
            fillContentTree(lastModule);
        }
    }//GEN-LAST:event_documentedCheckboxActionPerformed

    private void contentTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_contentTreeValueChanged
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)evt.getPath().getLastPathComponent();
        Object obj = node.getUserObject();
        if (obj instanceof CodeObject)
            infoPanel.fill((CodeObject)obj);
    }//GEN-LAST:event_contentTreeValueChanged

    private int[] sliderPosition = new int[2];
    private void hideButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideButtonActionPerformed
        boolean v = !modulePanel.isVisible();

        if (!v) {
            sliderPosition[0] = splitPane.getDividerLocation();
            sliderPosition[1] = jSplitPane1.getDividerLocation();
        } else {
            splitPane.setDividerLocation(sliderPosition[0]);
            jSplitPane1.setDividerLocation(sliderPosition[1]);
        }

        updateUI();

        modulePanel.setVisible(v);
        contentTreePanel.setVisible(v);

        hideButton.setText(v?"<":">");

    }//GEN-LAST:event_hideButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTree contentTree;
    private javax.swing.JPanel contentTreePanel;
    private javax.swing.JCheckBox documentedCheckbox;
    private javax.swing.JButton hideButton;
    private de.blitzcoder.collide.gui.docs.InfoPanel infoPanel;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JPanel modulePanel;
    private javax.swing.JTree moduleTree;
    private javax.swing.JSplitPane splitPane;
    // End of variables declaration//GEN-END:variables
}
